﻿
apolloChart = function (container, opts) {
    this.container = container;
    this.columnModels = opts.columnModels;
    this.ajaxUrl = opts.ajaxUrl;
    this.dimensions = opts.dimensions;
    this.metrics = opts.metrics;
    this.tick = opts.tick;
    this.legendContainer = opts.legendContainer;

    this.init();
}



apolloChart.prototype.init = function () {
    // parse metrics
    var mtrcs = [];
    for (var i = 0; i < this.metrics.length; i++) {
        var metricIndex = -1;

        for (var j = 0; j < this.columnModels.length; j++) {
            if (this.metrics[i] == this.columnModels[j].index) {
                metricIndex = j;
                break;
            }
        }

        mtrcs.push({ name: this.metrics[i], index: metricIndex, columnModel: this.columnModels[metricIndex] });
    }
    this.metrics = mtrcs;


    // parse hierarhical dimensions - TODO
    this.dimension = this.getHierarhicalDimension(0);
    var currentDimension = this.dimension;

    for (var i = 1; i < this.dimensions.length; i++) {
        var subDimension = this.getHierarhicalDimension(i);

        if (subDimension != null) {
            currentDimension.subdimension = subDimension;
            currentDimension = subDimension;
        }
    }
    //alert(JSON.stringify(this.dimension));

    // parse dimensions
    var dmsns = [];
    for (var i = 0; i < this.dimensions.length; i++) {
        var dimensionIndex = -1;

        for (var j = 0; j < this.columnModels.length; j++) {
            if (this.dimensions[i] == this.columnModels[j].index) {
                dimensionIndex = j;
                break;
            }
        }

        dmsns.push({ name: this.dimensions[i], index: dimensionIndex, columnModel: this.columnModels[dimensionIndex] });
    }
    this.dimensions = dmsns;


    // parse ticks
    if (this.tick != null) {
        for (var j = 0; j < this.columnModels.length; j++) {
            if (this.tick == this.columnModels[j].index) {
                var aux = { name: this.tick, index: j, columnModel: this.columnModels[j] };
                this.tick = aux;
                break;
            }
        }
    }


    // make request to JSON
    var that = this;
    var maxRecords = 2000;
    var data = "rows=" + maxRecords;

    // order by tick
    if (this.tick != null)
        data += "&sidx=" + this.tick.name + "&sord=asc";

    // request
    $.ajax({
        url: that.ajaxUrl,
        data: data,
        dataType: "json",
        success: function (jsonResponse) {
            if (jsonResponse.records != "??" && jsonResponse.records > maxRecords)
                alert("The dataset was truncated to " + maxRecords + " records out of " + jsonResponse.records + " records!");

            that.onLoad(jsonResponse);
        }
    });
}

apolloChart.prototype.getHierarhicalDimension = function (dimensionIndex) {
    for (var j = 0; j < this.columnModels.length; j++) {
        if (this.dimensions[dimensionIndex] == this.columnModels[j].index) {
            return { name: this.dimensions[dimensionIndex], index: j, columnModel: this.columnModels[j] }
        }
    }

    return null;
}

apolloChart.prototype.onLoad = function (jsonResults) {
    this.rows = jsonResults.rows;
    this.records = jsonResults.records;
    this.page = jsonResults.page;
    this.total = jsonResults.total;

    this.parseTicks();

    this.parseRecords();

    var options = {
        series: {
            lines: { show: true }
        },
        legend: { show: true }
    };


    var series = [];
    if (this.dimensions.length > 0) {
        for (var dIdx = 0; dIdx < this.dimensions.length; dIdx++) {
            for (var sIdx = 0; sIdx < this.dimensions[dIdx].series.length; sIdx++) {
                series.push(this.dimensions[dIdx].series[sIdx]);
            }
        }
    }
    else {
        for (var sIdx = 0; sIdx < this.dimensions[dIdx].series.length; sIdx++) {
            series.push(this.dimensions[dIdx].series[sIdx]);
        }
    }


    if (this.legendContainer != null)
        options.legend.container = this.legendContainer;

    if (this.tick != null) {
        if (options.xaxis == null)
            options.xaxis = {};

        options.xaxis.ticks = this.getTickLabels();
        options.xaxis.label = this.tick.columnModel.displayName;
    }

    $.plot(this.container, series, options);

    this.legendContainer.prepend($("<div>").text(this.tick.name + " / " + this.metrics[0].name));
}

apolloChart.prototype.getTickLabels = function () {
    
    if (this.tick.columnModel.formatter != null) {

        var formattedValues = [];

        for (var tIdx = 0; tIdx < this.tick.data.length; tIdx++) {
            formattedValues.push([this.tick.data[tIdx][0], this.tick.columnModel.formatter(this.tick.data[tIdx][1], null, null)]);
        }

        return formattedValues;
    }

    return this.tick.data;
}

apolloChart.prototype.parseTicks = function () {
    // parse ticks
    if (this.tick != null) {
        this.tick.data = [];
        for (var rIdx = 0; rIdx < this.rows.length; rIdx++) {

            var tickValue = this.rows[rIdx].cell[this.tick.index].replace(/<[^>]*>?/gm, '');

            var foundTick = false;

            for (var tIdx = 0; tIdx < this.tick.data.length; tIdx++) {
                if (this.tick.data[tIdx][1] == tickValue) {
                    foundTick = true;
                    break;
                }
            }

            if (!foundTick)
                this.tick.data.push([(this.tick.data.length + 1), tickValue]);
        }
    }
}

apolloChart.prototype.parseRecords = function () {
    // parse values
    for (var rIdx = 0; rIdx < this.rows.length; rIdx++) {

        for (var dIdx = 0; dIdx < this.dimensions.length; dIdx++) {
            for (var mIdx = 0; mIdx < this.metrics.length; mIdx++) {

                var currentSerie = this.findSerie(
                      this.dimensions[dIdx]
                    , this.metrics[mIdx]
                    , this.rows[rIdx].cell[this.dimensions[dIdx].index].replace(/<[^>]*>?/gm, '')
                );

                if (this.tick != null) {
                    currentSerie.data.push([
                          (currentSerie.data.length + 1)
                        , this.rows[rIdx].cell[this.metrics[mIdx].index]
                    ]);
                } else {
                    currentSerie.data.push([
                          this.findTick(this.rows[rIdx].cell[this.tick.index])
                        , this.rows[rIdx].cell[this.metrics[mIdx].index]
                    ]);
                }

            }
        }
    }
}

apolloChart.prototype.findSerie = function (dimension, metric, dimensionValue) {
    if(dimension.series == null)
        dimension.series = [];

    for (var sIdx = 0; sIdx < dimension.series.length; sIdx++) {
        if (dimension.series[sIdx].metricIndex == metric.index && dimension.series[sIdx].label == dimensionValue) {
            return dimension.series[sIdx];
        }
    }

    dimension.series.push({ label: dimensionValue, metricIndex: metric.index, data: [] });

    return dimension.series[dimension.series.length - 1];
}

apolloChart.prototype.findTick = function (tickValue) {
    for (var tIdx = 0; tIdx < this.tick.data.length; tIdx++) {
        if (this.tick.data[tIdx][1] == tickValue) {
            return this.tick.data[tIdx][0];
        }
    }

    return 0;
}